package loginsvc

import (
	"fmt"
	"server/application/dto/requestdto"
	"server/application/dto/responddto"
	"server/pkg/mylog"
	"server/pkg/request"
	"server/pkg/utils"
	"server/setting"
)

// 获取用户级凭证api  https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/account-api-obtain-user-token-V5
const apiHuaweiAuth = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"

// 解析凭证
const apiHuaweiParseAccessToken = "https://oauth-api.cloud.huawei.com/rest.php?nsp_fmt=JSON&nsp_svc=huawei.oauth2.user.getTokenInfo"

type HuahuaweiLoginService struct {
}

// 构造函数
func NewHuaweiLoginService() *HuahuaweiLoginService {
	return new(HuahuaweiLoginService)
}

// 华为登录验证  成功则返回UnionID
func (h *HuahuaweiLoginService) LoginVerify(params *requestdto.UserAccountLoginHuawei) (string, error) {
	//第一步：根据code信息获取凭证Access Token(用户级)
	authData, err := h.getAccessToken(&requestdto.HuaweiAuth{
		ClientID:     setting.HuaweiAppClientId,
		ClientSecret: setting.HuaweiAppClientSecret,
		Code:         params.AuthorizationCode,
		GrantType:    "authorization_code", //固定值
	})
	if err != nil {
		mylog.Error("huawei login  LoginVerify" + "getAccessToken" + err.Error())
		return "", err
	}

	//第二步：【解析验证】得到的凭证Access Token   得到获取用户的UnionID
	tokenInfo, err := h.parseAccessToken(authData.AccessToken, params.OpenID)
	if err != nil {
		mylog.Error("huawei login LoginVerify" + "parseAccessToken" + err.Error())
		return "", err
	}
	if tokenInfo == nil || tokenInfo.UnionID == "" {
		return "", fmt.Errorf("tokenInfo.UnionID is empty")
	}
	return tokenInfo.UnionID, nil
}

// 第一步根据code信息获取凭证Access Token(用户级)
func (h *HuahuaweiLoginService) getAccessToken(params *requestdto.HuaweiAuth) (*responddto.HuaweiAuthResponse, error) {
	//第一步：根据code信息获取凭证Access Token(用户级)
	req := request.NewRequest(apiHuaweiAuth, request.HttpTypePost)
	req.SetHeader("Content-Type", "application/x-www-form-urlencoded")
	req.SendData = params
	respAuth, err := req.Send()
	if err != nil {
		return nil, err
	}
	if respAuth.StatusCode != 200 {
		mapData, err := request.ResponseToMap(respAuth)
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("respAuth.StatusCode != 200" + utils.DataToJsonStr(mapData))
	}

	authData := &responddto.HuaweiAuthResponse{}
	request.ResponseToData(respAuth, authData)

	if authData == nil {
		return nil, fmt.Errorf("authData is nil")
	}

	if authData.AccessToken == "" {
		return nil, fmt.Errorf("authData.AccessToken is empty")
	}
	return authData, nil
}

// 第二步：【解析验证】得到的凭证Access Token
func (h *HuahuaweiLoginService) parseAccessToken(accessToken, openid string) (*responddto.HuaweiParseAccessTokenSuccess, error) {
	req2 := request.NewRequest(apiHuaweiParseAccessToken, request.HttpTypePost)
	req2.SetHeader("Content-Type", "application/x-www-form-urlencoded")
	req2.SendData = &requestdto.HuaweiParseAccessToken{
		AccessToken: accessToken,
		OpenID:      openid,
	}
	respTokenInfo, err := req2.Send()
	if err != nil {
		return nil, err
	}

	if respTokenInfo.StatusCode != 200 {
		mapData, err := request.ResponseToMap(respTokenInfo)
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("respAuth.StatusCode != 200" + utils.DataToJsonStr(mapData))
	}

	tokenInfo := &responddto.HuaweiParseAccessTokenSuccess{}

	request.ResponseToData(respTokenInfo, tokenInfo)
	if tokenInfo == nil {
		return nil, fmt.Errorf("tokenInfo is nil")
	}
	if tokenInfo.Error != "" {
		return nil, fmt.Errorf("tokenInfo.Error != ''" + tokenInfo.Error)
	}

	return tokenInfo, nil

}
